<template>
  <div :class="{ fullscreen: state.fullscreen }" class="tinymce-container" :style="{ width: containerWidth }">
    <textarea :id="state.tinymceId" class="tinymce-textarea" />
    <div class="editor-custom-btn-container">
        <span @click="imgHandler">导入图片</span>
    </div>
  </div>
   <!-- 使用自定义图片上传 -->
   <input type="file" hidden accept=".jpg,.png" ref="fileBtn" @change="handleUpload" />
</template>

<script lang="ts" setup >

import plugins from './plugins'
import toolbar from './toolbar'
import load from './dynamicLoadScript'
import { computed, reactive, nextTick, watch,onMounted,onActivated,onBeforeUnmount,onDeactivated,ref} from 'vue';
import {message} from "ant-design-vue";
const tinymceCDN = 'https://cdn.bootcdn.net/ajax/libs/tinymce/4.9.3/tinymce.min.js'
const url= import.meta.env.VITE_APP_UPLOAD_URL+"/uploads"
  const imageUrl =import.meta.env.VITE_APP_IMAGE_URL;
  const fileBtn = ref();
const props = withDefaults(defineProps<{
  id: string;
  value: string;
  toolbar: any[];
  menubar: string;
  height: number | string;
  width: number | string;
}>(), {
  id: 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + ''),
  value: "",
  toolbar: () => [],
  menubar: 'file edit insert view format table',
  height: 400,
  width: "auto"
})

const state = reactive({
  hasChange: false,
  hasInit: false,
  tinymceId: props.id,
  fullscreen: false,
  languageTypeList: {
    'en': 'en',
    'zh': 'zh_CN',
    'es': 'es_MX',
    'ja': 'ja'
  }
})

const emit = defineEmits<{
  (e:"update:value",value:string):void
}>()

const containerWidth = computed(() => {
  const width = props.width;
  if (/^[\d]+(\.[\d]+)?$/.test(`${width}`)) { // matches `100`, `'100'`
    return `${width}px`
  }
  return width
})

watch(() => props.value, (val) => {
  if (!state.hasChange && state.hasInit) {
    //@ts-ignore
    nextTick(() => window.tinymce.get(state.tinymceId).setContent(val || ''))
  }
})



onMounted(()=>{
  init()
})

onActivated(()=>{
  //@ts-ignore
  if (window.tinymce) {
    initTinymce()
  }
})

onBeforeUnmount(()=>{
  destroyTinymce()
})

onDeactivated(()=>{
  destroyTinymce()
})

const init = ()=> {
    // dynamic load tinymce from cdn
    load(tinymceCDN, (err) => {
      if (err) {
        message.error(err.message)
        return
      }
      initTinymce()
    })
  }

  const initTinymce = ()=> {
    //@ts-ignore
    window.tinymce.init({
      selector: `#${state.tinymceId}`,
      language: state.languageTypeList['en'],
      height: props.height,
      body_class: 'panel-body ',
      object_resizing: false,
      toolbar: props.toolbar.length > 0 ? props.toolbar : toolbar,
      menubar: props.menubar,
      plugins: plugins,
      end_container_on_empty_block: true,
      powerpaste_word_import: 'clean',
      code_dialog_height: 450,
      code_dialog_width: 1000,
      advlist_bullet_styles: 'square',
      advlist_number_styles: 'default',
      imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
      default_link_target: '_blank',
      link_title: false,
      nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
      init_instance_callback: editor => {
        if (props.value) {
          editor.setContent(props.value)
        }
        state.hasInit = true
        editor.on('NodeChange Change KeyUp SetContent', () => {
          state.hasChange = true
          emit('update:value', editor.getContent())
        })
      },
      setup(editor) {
        editor.on('FullscreenStateChanged', (e) => {
          state.fullscreen = e.state
        })
      },
      convert_urls: false

    })
  }

  const destroyTinymce = () =>{
    //@ts-ignore
    const tinymce = window.tinymce.get(state.tinymceId)
    if (state.fullscreen) {
      tinymce.execCommand('mceFullScreen')
    }

    if (tinymce) {
      tinymce.destroy()
    }
  }

  const imgHandler = (state:any) => {
      fileBtn.value.click()
  }

 const setContent =(value)=> {
  //@ts-ignore
    window.tinymce.get(state.tinymceId).setContent(value)
  }
  const getContent=()=> {
    //@ts-ignore
    window.tinymce.get(state.tinymceId).getContent()
  }
  const imageSuccessCBK=(url)=> {
    //@ts-ignore
    window.tinymce.get(state.tinymceId).insertContent(`<img class="wscnph" src="${url}" >`)
  }

  const handleUpload = (e:any) => {
    const files = Array.prototype.slice.call(e.target.files)
    console.log(files, "files")
    if (!files) {
      return
    }
    const formdata = new FormData()
    formdata.append('file', files[0])
    console.log("file--->",files[0])
    doUpload(formdata);  // 此处使用服务端提供上传接口
  }

  /**
 * 发送上传请求
 * @param file
 * @param sign
 * @private
 */
const doUpload = (file: any) => {
  const uploadForm = new FormData();
  uploadForm.append('file', file);
  const xhr = new XMLHttpRequest();
  // 上传进度监听
  xhr.upload.onprogress = function (e) {
    if (e.type == 'progress') {
      const percent = Math.round((e.loaded / e.total) * 100);
    }
  };

  // 上传结果
  xhr.onreadystatechange = function (e) {
    if (xhr.readyState == 4) {
      if (xhr.status == 200 || xhr.status == 201 || xhr.status == 204) {
        console.log("res--->",xhr)
        if (xhr.response) {
          let data =JSON.parse(xhr.response);
          imageSuccessCBK(imageUrl+data.key)
        }
        console.log(
          `%c OSS %c 上传成功 %c`,
          'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
          'background:#41b883 ; padding: 1px; border-radius: 0 3px 3px 0;  color: #fff',
          'background:transparent',
        );
      } else {
      }
    }
  };

  xhr.open('POST', url);
  xhr.send(file);
};
</script>

<style lang="less" scoped>
.tinymce-container {
  position: relative;
  line-height: normal;
}

.tinymce-container {
    deep(.mce-fullscreen) {
      z-index: 10000;
    }

}

.tinymce-textarea {
  visibility: hidden;
  z-index: -1;
}

.editor-custom-btn-container {
  position: absolute;
  right: 4px;
  top: 4px;
  /*z-index: 2005;*/
}

.fullscreen .editor-custom-btn-container {
  z-index: 10000;
  position: fixed;
}

.editor-upload-btn {
  display: inline-block;
}
</style>
